package conn

import (
	"errors"
	"gitee.com/cooge/impush/core"
	"gitee.com/cooge/impush/gutil"
	"gitee.com/cooge/impush/message"
	"gitee.com/cooge/impush/xhttp/cache"
	"net"
	"sync"
	"time"
)

type CHttpConn struct {
	UserId    string
	list      *gutil.Linklist
	lock      *sync.RWMutex
	address   string
	BreakTime time.Time
	DealTime  int
}

func DealHttpConn(conn *net.TCPConn, userId string, deal int) *CHttpConn {
	hc := NewHttpConn(userId)
	ihc := core.GetSetOneUser(userId, hc)
	xhc, ok := ihc.(*CHttpConn)
	if ok {
		xhc.dealConn(conn, deal, userId)
		xhc.DealTime = deal
		xhc.BreakTime = time.Now()
		return xhc
	} else {
		core.DeleteUser(userId, xhc)
	}
	return nil
}

func NewHttpConn(userId string) *CHttpConn {
	var hc CHttpConn
	hc.UserId = userId
	hc.lock = new(sync.RWMutex)
	return &hc
}
func (this *CHttpConn) ConnNum() int {
	return this.list.Len()
}

func (this *CHttpConn) ConnArray() []interface{} {
	return this.list.GetAllArray()
}

func (this *CHttpConn) IsExpire() bool {
	if this.list.Len() == 0 {
		return this.BreakTime.Add(time.Duration(this.DealTime) * time.Second).Before(time.Now())
	}
	return false

}

func (this *CHttpConn) SendMessage(msg *message.Message) (int, error) {
	is := this.list.GetAllArray()
	for _, v := range is {
		hv, ok := v.(*CHTCPconn)
		if ok {
			num, err := hv.SendMessage(msg)
			if err == nil {
				return num, err
			}
		}
	}
	cache.AddMessgeCache(this.UserId, msg)
	return 0, nil
}

func (this *CHttpConn) SendMessages(msgs []*message.Message) (int, error) {
	is := this.list.GetAllArray()
	for _, v := range is {
		hv, ok := v.(*CHTCPconn)
		if ok {
			num, err := hv.SendMessages(msgs)
			if err == nil {
				return num, err
			}
		}
	}
	return 0, errors.New("error fail")
}

func (this *CHttpConn) GetUser() string {
	return this.address
}

func (this *CHttpConn) Close(userId string) error {
	core.DeleteUser(userId, this)
	return nil
}

func (this *CHttpConn) dealConn(conn *net.TCPConn, deal int, userId string) {
	this.lock.Lock()
	nhp := NewCHTCPconn(conn, deal, userId)
	if this.list == nil {
		this.list = gutil.NewLinkList()
	}
	this.list.Add(nhp)
	nhp.Start(func(pconn *CHTCPconn) {
		this.list.Delete(pconn)
		this.BreakTime = time.Now()

	})
	this.address = conn.RemoteAddr().String()
	this.lock.Unlock()
}
